package com.shuyun.limiter;

import com.google.common.util.concurrent.RateLimiter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: shuai.chen@shuyun.com
 * @date: 2022/12/23 11:43 AM
 */
@Slf4j
@RestController
@RequestMapping("/limit")
public class LimitController {

    /**
     * 限流策略 ： 1秒钟2个请求
     */
    private final RateLimiter limiter = RateLimiter.create(1.0);

    private final Map<String, RateLimiter> rateLimiterMap = new ConcurrentHashMap<>();

    private DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @GetMapping("/test1")
    public String testLimiter() {
        // 没拿到令牌，就直接进入服务降级
        boolean tryAcquire = limiter.tryAcquire(1);

        if (!tryAcquire) {
            log.warn("进入服务降级，时间{}", LocalDateTime.now().format(dtf));
            return "当前排队人数较多，请稍后再试！";
        }

        log.info("获取令牌成功，时间{}", LocalDateTime.now().format(dtf));
        return "请求成功";
    }

    @GetMapping("/test2")
    public String testLimiter2(String appId) {
        if (!rateLimiterMap.containsKey(appId)) {
            rateLimiterMap.put(appId, RateLimiter.create(1.0));
        }
        // 走限流
        boolean tryAcquire = rateLimiterMap.get(appId).tryAcquire();
        if (!tryAcquire) {
            log.warn("进入服务降级，时间{}", LocalDateTime.now().format(dtf));
            return "当前排队人数较多，请稍后再试！";
        }
        log.info("获取令牌成功，时间{}", LocalDateTime.now().format(dtf));
        return "请求成功";
    }

}
